<?php
namespace App\Models\AuthManage;

use App\Facades\ScarecrowAuth;
use Illuminate\Support\Facades\DB;

/**
 * 权限管理控制器
 * Class AuthManageModel
 * @package app\back\model
 */
class AuthModel {
	/**
	 * 创建权限
	 * @param $data
	 * @return array
	 * @throws \Exception
	 */
	public function createAuth($data) {
		$nowTime = time();
		$insertData = [
			'name'		=>	$data['name'],
			'description'	=>	isset($data['description']) ? $data['description'] : "",
			'sort'		=>	isset($data['sort']) ? $data['sort'] : 0,
			'create_time'	=>	$nowTime,
			'update_time'	=>	$nowTime,
			'status'	=>	1
		];

		$iCnt = DB::table('sc_system_authority')->insert($insertData);
		if ($iCnt) {
			HandleLog()->addLog('i', $data, '创建了权限:'.$data['name']);
			return ModelReturn(0, '创建成功');
		} else {
			return ModelReturn(1, '创建失败');
		}
	}

	/**
	 * 编辑权限
	 * @param $data
	 * @return array
	 * @throws \Exception
	 */
	public function editAuth($data)
	{
		$id = $data['id'];
		$authObj = DB::table('sc_system_authority')->whereRaw("id=? AND status!=9", [$id])->first();
		if (!$authObj) {
			return ModelReturn(1, '权限未找到');
		}

		$nowTime = time();
		$updateData = [
			'name'		=>	$data['name'],
			'description'	=>	isset($data['description']) ? $data['description'] : "",
			'update_time'	=>	$nowTime,
		];

		$iCnt = DB::table('sc_system_authority')->whereRaw("id=?", [$id])->update($updateData);
		if ($iCnt) {
			HandleLog()->addLog('u', $data, '编辑了权限' . $authObj->name);
			return ModelReturn(0, '编辑成功');
		} else {
			return ModelReturn(1, '编辑失败');
		}
	}

	/**
	 * 删除权限
	 * @param $id
	 * @return array
	 * @throws \Exception
	 */
	public function deleteAuth($id) {
		$authObj = DB::table('sc_system_authority')->whereRaw("id=? AND status!=9", [$id])->first();
		if (!$authObj) {
			return ModelReturn(1, '权限未找到');
		}

		$updateData = [
			'status'	=>	9,
			'update_time'	=>	time()
		];
		$iCnt = DB::table('sc_system_authority')->whereRaw("id=?", [$id])->update($updateData);
		if ($iCnt) {
			HandleLog()->addLog('d', ['id'=>$id], '删除了权限' . $authObj->name);
			return ModelReturn(0, '删除成功');
		} else {
			return ModelReturn(2, '删除失败');
		}
	}

	/**
	 * 获取权限详情
	 * @param $id
	 * @return array
	 */
	public function getAuth($id) {
		$authObj = DB::table('sc_system_authority')->whereRaw("id=? AND status!=9", [$id])->first();
		if (!$authObj) {
			return ModelReturn(1, '权限未找到');
		}
		$authObj = (array)$authObj;
		$authObj['createTimeStr'] = date("Y-m-d H:i:s", $authObj['create_time']);
		$authObj['updateTimeStr'] = date("Y-m-d H:i:s", $authObj['update_time']);
		return ModelReturn(0, '获取成功', $authObj);
	}

	/**
	 * 获取权限列表
	 * @return array
	 */
	public function getAuthList() {
		$authList = DB::table('sc_system_authority')->whereRaw("status!=9")->get();
		$authList = DbObjectToArr($authList);

		array_walk($authList, function (&$item) {
			$item['createTimeStr'] = date("Y-m-d H:i:s", $item['create_time']);
			$item['updateTimeStr'] = date("Y-m-d H:i:s", $item['update_time']);
		});

		return ModelReturn(0, '获取成功', $authList);
	}

	/**
	 * 获取权限列表分页
	 * @param int $page
	 * @param int $limit
	 * @return array
	 */
	public function getAuthListPage($page=1, $limit=10) {
		$index = ($page - 1) * $limit;
		$authList = DB::table('sc_system_authority')->whereRaw("status!=9")->offset($index)->limit($limit)->get();
		$total = DB::table('sc_system_authority')->whereRaw("status!=9")->count('id');
		$authList = DbObjectToArr($authList);
		array_walk($authList, function (&$item) {
			$item['createTimeStr'] = date("Y-m-d H:i:s", $item['create_time']);
			$item['updateTimeStr'] = date("Y-m-d H:i:s", $item['update_time']);
		});

		$data = [
			'total'	=>	$total,
			'list'	=>	$authList,
			'limit'	=>	$limit,
			'page'	=>	$page
		];
		return ModelReturn(0, '获取成功', $data);
	}

	/**
	 * 创建角色
	 * @param $data
	 * @return array
	 * @throws \Exception
	 */
	public function createRole($data) {
		$nowTime = time();
			$insertData = [
			'name'		=>	$data['roleName'],
			'description'	=>	isset($data['description']) ? $data['description'] : "",
			'sort'		=>	isset($data['sort']) ? $data['sort'] : 0,
			'create_time'	=>	$nowTime,
			'update_time'	=>	$nowTime,
			'status'	=>	1
		];

		$iCnt = DB::table('sc_system_role')->insert($insertData);
		if ($iCnt) {
			HandleLog()->addLog('i', $data, '创建了角色:'.$data['roleName']);
			return ModelReturn(0, '创建成功');
		} else {
			return ModelReturn(1, '创建失败');
		}
	}

	/**
	 * 编辑角色
	 * @param $data
	 * @return array
	 * @throws \Exception
	 */
	public function editRole($data)
	{
		$id = $data['roleId'];
		$roleObj = DB::table('sc_system_role')->whereRaw("id=? AND status!=9", [$id])->first();
		if (!$roleObj) {
			return ModelReturn(1, '权限未找到');
		}

		$nowTime = time();
		$updateData = [
			'name'		=>	$data['roleName'],
			'description'	=>	isset($data['description']) ? $data['description'] : "",
			'update_time'	=>	$nowTime
		];

		$iCnt = DB::table('sc_system_role')->whereRaw("id=?", [$id])->update($updateData);
		if ($iCnt) {
			HandleLog()->addLog('u', $data, '编辑了角色' . $roleObj->name);
			return ModelReturn(0, '编辑成功');
		} else {
			return ModelReturn(2,'编辑失败');
		}
	}

	/**
	 * 删除角色
	 * @param $id
	 * @return array
	 * @throws \Exception
	 */
	public function deleteRole($id) {
		$roleObj = DB::table('sc_system_role')->whereRaw("id=? AND status!=9", [$id])->first();
		if (!$roleObj) {
			return ModelReturn(1, '角色未找到');
		}

		$updateData = [
			'status'	=>	9,
			'update_time'	=>	time()
		];
		$iCnt = DB::table('sc_system_role')->whereRaw("id=?", [$id])->update($updateData);
		if ($iCnt) {
			HandleLog()->addLog('d', ['id'=>$id], '删除了角色' . $roleObj->name);
			return ModelReturn(0, '删除成功');
		} else {
			return ModelReturn(2, '删除失败');
		}
	}

	/**
	 * 获取角色详情
	 * @param $id
	 * @return array
	 */
	public function getRole($id) {
		$roleObj = DB::table('sc_system_role')->whereRaw("id=? AND status!=9", [$id])->first();
		if (!$roleObj) {
			return ModelReturn(1, '角色未找到');
		}
		$roleObj = (array)$roleObj;
		$roleObj['createTimeStr'] = date("Y-m-d H:i:s", $roleObj['create_time']);
		$roleObj['updateTimeStr'] = date("Y-m-d H:i:s", $roleObj['update_time']);
		return ModelReturn(0, '获取成功', $roleObj);
	}

	/**
	 * 获取角色列表分页
	 * @param $page
	 * @param $limit
	 * @return array
	 */
	public function getRoleListPage($page, $limit) {
		$index = ($page - 1) * $limit;
		$authList = DB::table('sc_system_role')->whereRaw("status!=9")->offset($index)->limit($limit)->get();
		$total = DB::table('sc_system_role')->whereRaw("status!=9")->count('id');
		$authList = DbObjectToArr($authList);
		array_walk($authList, function (&$item) {
			$item['createTimeStr'] = date("Y-m-d H:i:s", $item['create_time']);
			$item['updateTimeStr'] = date("Y-m-d H:i:s", $item['update_time']);
		});
		$data = [
			'total'	=>	$total,
			'list'	=>	$authList,
			'limit'	=>	$limit,
			'page'	=>	$page
		];
		return ModelReturn(0, '获取成功', $data);
	}

	/**
	 * 获取角色列表
	 * @return array
	 */
	public function getRoleList() {
		$authList = DB::table('sc_system_role')->whereRaw("status!=9")->get();
		$authList = DbObjectToArr($authList);
		return ModelReturn(0, '获取成功', $authList);
	}

	/**
	 * 获取角色拥有的权限列表
	 * @param $id
	 * @return array
	 */
	public function getRoleAuthList($id) {
		$roleObj = DB::table('sc_system_role')->whereRaw("id=? AND status!=9", [$id])->first();
		if (!$roleObj) {
			return ModelReturn(1, '角色未找到');
		}
		$allAuthList = DB::table('sc_system_role_authority as t1')->leftJoin('sc_system_authority as t2', 't1.authority_id','=','t2.id')->where(['t1.role_id'=>$id])->select(['t2.*','t1.role_id'])->get();
		$allAuthList = DbObjectToArr($allAuthList);
		return ModelReturn(0, '获取成功', $allAuthList);
	}

	/**
	 * 用户绑定角色
	 * @param $allRoleId
	 * @param $allData
	 * @return array
	 */
	public function roleBindUser($allRoleId, $allData) {
		$userId = $allData['userId'];

		$userObj = DB::table('sc_user')->whereRaw("id=?", [$userId])->first();
		if (!$userObj) {
			return ModelReturn(1, '用户未找到');
		}

		$allBindRoleId = DB::table('sc_system_role')->whereIn('id', $allRoleId)->whereRaw('status!=9')->pluck('id')->toArray();

		$allBindedRoleId = DB::table('sc_system_role_user')->where(['user_id'=>$userId])->pluck('role_id')->toArray();
		$neeDBindRoleId = array_diff($allBindRoleId, $allBindedRoleId);
		$deleteRoleId = array_diff($allBindedRoleId, $allBindRoleId);

		$insertData = [];
		foreach ($neeDBindRoleId as $item) {
			$insertData[] = [
				'role_id'	=>	$item,
				'user_id'	=>	$userId
			];
		}

		try{
			DB::beginTransaction();
			DB::table('sc_system_role_user')->where('user_id', $userId)->whereIn('role_id', $deleteRoleId)->delete();
			if ($insertData) {
				DB::table('sc_system_role_user')->insert($insertData);
			}
			HandleLog()->addLog('i', ['user_id'=>$userId, 'role_id'=>$allRoleId], '分配了角色给' . $userObj->username);
			DB::commit();
			return ModelReturn(0, '绑定成功');
		} catch (\Exception $e) {
			DB::rollback();
			return ModelReturn(2, '绑定失败');
		}
	}

	/**
	 * 获取当前用户菜单
	 * @return array
	 */
	public function getUserAllMenu() {
		$userId = ScarecrowAuth::id();
		$isAdmin = ScarecrowAuth::isAdmin();
		if ($isAdmin) {
			$allMenuList = $this->getSupperAdminMenuList();
		} else {
			$allMenuList = $this->getUserMenuList($userId);
		}

		return ModelReturn(0, '获取成功', $allMenuList);
	}

	/**
	 * 获取菜单的树状结构
	 * @param bool $isAllCanDistribution
	 * @param array $canHandleFunctionList
	 * @return array
	 */
	protected function getMenuListTree($isAllCanDistribution=false, $canHandleFunctionList=[]) {
		$allMenuList = DB::table('sc_system_menu')->whereRaw('status!=9')->orderByRaw('sort desc,create_time desc')->get();
		$allMenuList = DbObjectToArr($allMenuList);
		if ($isAllCanDistribution) {
			$allFunctionListObj = DB::table('sc_system_function')->where('status', 1)->orderByRaw('id')->get();
		} else {
			$allFunctionListObj = DB::table('sc_system_function')->where('status', 1)->whereIn('id', $canHandleFunctionList)->orderBy(
				'id')->get();
		}

		$allFunctionListObj= DbObjectToArr($allFunctionListObj);

		$allFunctionList = [];
		foreach ($allFunctionListObj as $item) {
			$allFunctionList[$item['menu_id']][] = $item;
		}

		$menuTree = [];
		$allMenuListData = [];
		foreach ($allMenuList as $item) {
			$item['childList'] = [];
			$item['functionList'] = array_key_exists($item['id'], $allFunctionList) ? $allFunctionList[$item['id']] : [];
			$allMenuListData[$item['id']] = $item;
		}

		foreach ($allMenuListData as &$item) {
			if ($item['parent_id'] == 0) {
				$menuTree[$item['id']] = &$item;
			} else {
				if (array_key_exists($item['parent_id'], $allMenuListData)) {
					$allMenuListData[$item['parent_id']]['childList'][$item['id']] = &$item;
				}
			}
		}

		return $menuTree;
	}

	/**
	 * 清理无功能权限的菜单
	 * @param $menuListObj
	 * @param int $iCnt
	 * @return bool
	 */
	protected function clearMenuList(&$menuListObj, $iCnt=0) {
		$menuList = $menuListObj[$iCnt];
		if (empty($menuList['functionList']) && empty($menuList['childList'])) {
			unset($menuListObj[$iCnt]);
			return true;
		}

		foreach ($menuListObj[$iCnt]['childList'] as $key => $item) {
			$this->clearMenuList($menuListObj[$iCnt]['childList'], $key);
		}

		if (empty($menuListObj[$iCnt]['functionList']) && empty($menuListObj[$iCnt]['childList'])) {
			unset($menuListObj[$iCnt]);
			return true;
		}
		return true;
	}

	/**
	 * 获取用户所有有权限的菜单列表
	 * @param $userId
	 * @return array|mixed
	 */
	protected function getUserMenuList($userId) {
		$allFunctionId = DB::table('sc_system_role_user as t1')->leftJoin('sc_system_role_authority as t2', 't1.role_id','=','t2.role_id')->leftJoin('sc_system_authority_menu_function as t3', 't3.authority_id','=','t2.authority_id')->where('t1.user_id', $userId)->pluck('t3.function_id')->toArray();
		$allMenuList = $this->getMenuListTree(false, $allFunctionId);
		$nowMenuList = [0=>['childList'=>$allMenuList, 'functionList'=>[]]];
		$this->clearMenuList($nowMenuList);
		if ($nowMenuList) {
			$nowMenuList = $nowMenuList[0]['childList'];
		} else {
			$nowMenuList = [];
		}
		return $nowMenuList;
	}

	/**
	 * 获取所有权限的菜单列表
	 * @param $userId
	 * @return array|mixed
	 */
	protected function getSupperAdminMenuList() {
		$allFunctionId = DB::table('sc_system_authority_menu_function')->pluck('function_id')->toArray();

		$allMenuList = $this->getMenuListTree(false, $allFunctionId);
		$nowMenuList = [0=>['childList'=>$allMenuList, 'functionList'=>[]]];
		$this->clearMenuList($nowMenuList);
		if ($nowMenuList) {
			$nowMenuList = $nowMenuList[0]['childList'];
		} else {
			$nowMenuList = [];
		}
		return $nowMenuList;
	}

	/**
	 * 获取某个权限的所有功能
	 * @param $authId
	 * @return array
	 */
	public function getAuthToFunctionList($authId) {
		$authObj = DB::table('sc_system_authority')->where(['id'=>$authId])->first();
		if (!$authObj) {
			return ModelReturn(1, '权限未找到');
		}

		$allFunctionList = DB::table('sc_system_authority_menu_function')->where('authority_id', $authId)->pluck('function_id');
		$data = [
			'idList'	=>	$allFunctionList
		];
		return ModelReturn(0, '获取成功', $data);
	}

	/**
	 * 绑定权限与功能
	 * @param $authId
	 * @param $functionIdList
	 * @param $userId
	 * @return array
	 */
	public function authBindFunction($authId, $functionIdList, $userId) {
		$authObj = DB::table('sc_system_authority')->where(['id'=>$authId])->first();
		if (!$authObj) {
			return ModelReturn(1, '权限未找到');
		}

//		$allFunctionId = DB::table('sc_system_role_user as t1')->leftJoin('sc_system_role_authority as t2', 't1.role_id','=','t2.role_id')->leftJoin('sc_system_authority_menu_function  as t3', 't3.authority_id','=','t2.authority_id')->where('t1.user_id', $userId)->pluck('t3.function_id')->toArray();
//		DieDump($functionIdList);
//		$functionIdList = array_intersect($allFunctionId, $functionIdList);

		try {
			DB::beginTransaction();
			DB::table('sc_system_authority_menu_function')->where('authority_id', $authId)->delete();
			DB::table('sc_system_authority_menu')->where('authority_id', $authId)->delete();
			$allFunctionList = DB::table('sc_system_function')->whereIn('id', $functionIdList)->select(['id','menu_id'])->get();
			$allFunctionList = DbObjectToArr($allFunctionList);
			$insertData = [];
			$insertMenuData = [];
			foreach ($allFunctionList as $item) {
				$insertMenuData[$item['menu_id']] = [
					'authority_id'	=>	$authId,
					'menu_id'		=>	$item['menu_id']
				];
				$insertData[] = [
					'authority_id'	=>	$authId,
					'menu_id'		=>	$item['menu_id'],
					'function_id'	=>	$item['id']
				];
			}

			if ($insertData) {
				DB::table('sc_system_authority_menu_function')->insert($insertData);
			}

			if ($insertMenuData) {
				DB::table('sc_system_authority_menu')->insert($insertMenuData);
			}

			DB::commit();
			HandleLog()->addLog('i', ['authId'=>$authId, 'functionId'=>$functionIdList], '给权限分配了功能');
			return ModelReturn(0, '绑定成功');
		} catch (\Exception $e) {
			DB::rollback();
			return ModelReturn(2, '系统异常,请稍后再试');
		}
	}

	/**
	 * 角色绑定权限
	 * @param $roleId
	 * @param $allAuthId
	 * @return array
	 */
	public function roleBindAuth($roleId, $allAuthId) {
		$roleObj = DB::table('sc_system_role')->where(['id'=>$roleId])->first();
		if (!$roleObj) {
			return ModelReturn(1, '角色未找到');
		}

		$allBindedAuth = DB::table('sc_system_role_authority')->where('role_id', $roleId)->pluck('authority_id');
		$allBindedAuth = $allBindedAuth->toArray();
		$needDeleteAuthId = array_diff($allBindedAuth, $allAuthId);
		$neddInsterAuthId = array_diff($allAuthId, $allBindedAuth);
		$allInsertAuthId = DB::table('sc_system_authority')->whereIn('id', $neddInsterAuthId)->pluck('id')->toArray();

		$insertData = [];
		foreach ($allInsertAuthId as $item) {
			$insertData[] = [
				'role_id'	=>	$roleId,
				'authority_id'	=>	$item
			];
		}
		try {
			DB::beginTransaction();
			DB::table('sc_system_role_authority')->where('role_id', $roleId)->whereIn('authority_id', $needDeleteAuthId)->delete();
			if ($insertData) {
				DB::table('sc_system_role_authority')->insert($insertData);
			}
			DB::commit();
			HandleLog()->addLog('i', ['roleId'=>$roleId, 'allAuthId'=>$allAuthId], '给角色分配了权限');
			return ModelReturn(0, '绑定成功');
		} catch (\Exception $e) {
			DB::rollback();
			return ModelReturn(2, '系统异常,请稍后再试');
		}
	}
}